﻿using PhotoGallery.Data;
using PhotoGallery.Data.Entity;
using PhotoGallery.Data.Repository;
using PhotoGallery.Infrastructure;
using PhotoGallery.Models.Utils;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.IO;
using System.Linq;
using System.Web;

namespace PhotoGallery.Models
{
    public class AlbumInfo
    {
        public int ID { get; set; }
        [StringLength(25, ErrorMessageResourceType = typeof(ErrorMessages),
            ErrorMessageResourceName = "nameIsTooLong")]
        [LocalizedDisplayName("title", NameResourceType = typeof(Names))]
        public string Title { get; set; }
        [LocalizedDisplayName("folder", NameResourceType = typeof(Names))]
        public string FolderName { get; set; }
        public string FileName { get; set; }
        [DataType(DataType.Date)]
        [LocalizedDisplayName("date", NameResourceType = typeof(Names))]
        public DateTime? CreateDate { get; set; }        
        public SharedAlbum Shared { get; set; }
        // calculated
        public string Url { get; set; }
        public string UrlThumbnail { get; set; }
        public string FullFileName { get; set; }
    }

    public class AlbumsModel : BaseModel
    {
        string path, url;

        AlbumRepository repository ;

        public AlbumsModel()
        {
            path = BasePath + Settings.UploadsFolder + Owner + "\\";
            url = Settings.UploadsUrl + Owner + "/";
            repository = new AlbumRepository(Owner);
        }

        public IEnumerable<AlbumInfo> Get()
        {
            List<AlbumInfo> albums = new List<AlbumInfo>();
            var data = repository.Get();
            foreach(var entity in data)
            {
                var item = new AlbumInfo()
                {
                    ID = entity.ID,
                    Title = entity.Title,
                    FolderName = entity.FolderName,
                    FileName = entity.FileName,
                    CreateDate = entity.CreatedOn,
                    Shared = entity.Shared,

                    Url = url + entity.FileName,
                    UrlThumbnail = url  + entity.FileName,
                    FullFileName = path + entity.FileName
                };
                albums.Add(item);
            }
            return albums;
        }

        public AlbumInfo Get(int id)
        {
            var entity = repository.Get(id);
            var item = new AlbumInfo(){
                ID = entity.ID,
                Title = entity.Title,
                FolderName = entity.FolderName,
                FileName = entity.FileName,
                CreateDate = entity.CreatedOn,
                Shared = entity.Shared,

                Url = url + entity.FileName,
                FullFileName = path + entity.FileName
            };
            
            return item;
        }

        public int Create(AlbumInfo album, HttpPostedFileBase file)
        {
            var entity = new Album()
            {
                ID = album.ID,
                Title = album.Title,
                FolderName = album.FolderName,
                FileName = album.FileName,
                CreatedOn = album.CreateDate,
                Shared = album.Shared
            };
            entity.ID = repository.Create(entity);
            // Put album thumbnail
            if (file != null)
            {
                PutAlbumThumbnail(file, entity);

                repository.Update(entity);
            }
            
            return entity.ID;
        }

        private void PutAlbumThumbnail(HttpPostedFileBase file, Album entity)
        {
            entity.FileName = "album" + entity.ID.ToString() + Path.GetExtension(file.FileName);
            file.SaveAs(path + entity.FileName);
            string resizedFileName = "thumbnail-" + entity.FileName;
            FileHelper.SaveResizedImage(path, entity.FileName, resizedFileName);
            File.Delete(path + entity.FileName);
            entity.FileName = resizedFileName;
        }

        public void Update(AlbumInfo album, HttpPostedFileBase file)
        {
            var entity = Convert(album);
            if (file != null)
            {
                PutAlbumThumbnail(file, entity);
            }
            repository.Update(entity);
        }

        public void Delete(AlbumInfo album)
        {
            var entity = Convert(album);
            repository.Delete(entity);

        }

        public static Album Convert(AlbumInfo album)
        {
            var entity = new Album()
            {
                ID = album.ID,
                Title = album.Title,
                FolderName = album.FolderName,
                FileName = album.FileName,
                CreatedOn = album.CreateDate,
                Shared = album.Shared
            };
            return entity;
        }

        public int Erise(AlbumInfo album)
        {
            bool empty = IsEmpty(album.ID, album.FolderName ?? "album" + album.ID);
            if (empty)
            {
                string albumFolder = getAlbumFolder(album);
                string imageDirectory = path + "Images\\" + albumFolder;
                string photoDirectory = path + "Photos\\" + albumFolder;
                string videoDirectory = path + "Videos\\" + albumFolder;
                string audioDirectory = path + "Audio\\" + albumFolder;

                System.IO.Directory.Delete(imageDirectory, true);
                System.IO.Directory.Delete(photoDirectory, true);
                System.IO.Directory.Delete(videoDirectory, true);
                System.IO.Directory.Delete(audioDirectory, true);

                if (String.IsNullOrEmpty(album.FileName) && File.Exists(path + album.FileName))
                {
                    File.Delete(path + album.FileName);
                }
                return repository.Erise(album.ID);
            }
            else
            {
                return -1;
            }
        }

        private bool IsEmpty(int albumID, string albumFolder)
        {
            int count = 0;
            PhotoRepository p = new PhotoRepository(albumID, Owner, albumFolder);
            count += p.Get().Count();
            VideoRepository v = new VideoRepository(albumID, Owner, albumFolder);
            count += v.Get().Count();
            AudioRepository a = new AudioRepository(albumID, Owner, albumFolder);
            count += a.Get().Count();

            return count == 0;
        }

        private bool IsEmpty(int albumID)
        {
            int fileCount = 0;
            Album album = repository.Get(albumID);

            string imageDirectory = path + "Images\\" + getAlbumFolder(album);
            if (System.IO.Directory.Exists(imageDirectory))
            {
                List<string> arrFiles = System.IO.Directory.GetFiles(imageDirectory).ToList();
                arrFiles.Remove(imageDirectory + Settings.PhotoMetaDataXml);
                fileCount += arrFiles.Count();
            }
            string videoDirectory = path + "Videos\\" + getAlbumFolder(album);
            if (System.IO.Directory.Exists(videoDirectory))
            {
                List<string> arrFiles = System.IO.Directory.GetFiles(videoDirectory).ToList();
                arrFiles.Remove(videoDirectory + Settings.VideoMetaDataXml);
                arrFiles.Remove(videoDirectory + Settings.VideoAttachmentsMetaDataXml);
                fileCount += arrFiles.Count();
            }
            string audioDirectory = path + "Audio\\" + getAlbumFolder(album);
            if (System.IO.Directory.Exists(audioDirectory))
            {
                List<string> arrFiles = System.IO.Directory.GetFiles(audioDirectory).ToList();
                arrFiles.Remove(audioDirectory + Settings.AudioMetaDataXml);
                fileCount += arrFiles.Count();
            }
            return fileCount == 0;
        }

        protected string getAlbumFolder(AlbumInfo album)
        {
            if (album.FolderName == null || album.FolderName == String.Empty)
            {
                return Settings.AlbumFolder + album.ID + "\\";
            }
            else
            {
                return album.FolderName + "\\";
            }
        }
    }
}